home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / misc1 / iv26_w30.zip / SOURCES / WINTER.C < prev    next >
C/C++ Source or Header  |  1992-03-25  |  13KB  |  577 lines

  1. /*
  2.  *  MS Windows dependent Interactor Code
  3.  */
  4.  
  5. #include <InterViews\itable.h>
  6. #include <InterViews\bitmap.h>
  7. #include <InterViews\canvas.h>
  8. #include <InterViews\cursor.h>
  9. #include <InterViews\interact.h>
  10. #include <InterViews\sensor.h>
  11. #include <InterViews\shape.h>
  12. #include <InterViews\world.h>
  13. #include <InterViews\worldview.h>
  14. #include <InterViews\X11\eventrep.h>
  15. #include <InterViews\X11\worldrep.h>
  16. #include <InterViews\X11\windata.h>
  17.  
  18. const int NOGRAB = 0;
  19. const int LEFTGRAB = 1;
  20. const int MIDDLEGRAB = 2;
  21. const int RIGHTGRAB = 3;
  22.  
  23. POINT newPoint;
  24. HWND  hnewWindow;
  25. HWND  holdWindow = NULL;
  26. int   grabButton = NOGRAB;
  27.  
  28. inline void SetDummyOldWindow (HWND hWnd) {
  29.     holdWindow = nil;
  30. }
  31.  
  32. void EnterLeaveMessage () {
  33.     GetCursorPos(&newPoint);
  34.     hnewWindow = WindowFromPoint(newPoint);
  35.  
  36.     if (hnewWindow != holdWindow) {
  37.     if (IsChild(holdWindow, hnewWindow)) {
  38.         PostMessage(hnewWindow, WM_ENTERWINDOW, holdWindow, 0);
  39.     } else if (IsChild(hnewWindow, holdWindow)) {
  40.         PostMessage(holdWindow, WM_LEAVEWINDOW, hnewWindow, 0);
  41.     } else {
  42.         PostMessage(holdWindow, WM_LEAVEWINDOW, hnewWindow, 0);
  43.         PostMessage(hnewWindow, WM_ENTERWINDOW, holdWindow, 0);
  44.     }
  45.     }
  46.     holdWindow = hnewWindow;
  47. }
  48.  
  49. void PropagateEnterLeave (LPMSG m) {
  50.     HWND hWnd = GetParent(m->hwnd);
  51.  
  52.     switch (m->message) {
  53.  
  54.     case WM_ENTERWINDOW:
  55.     case WM_LEAVEWINDOW:
  56.         if ((hWnd != NULL) && (hWnd != m->wParam) &&
  57.            (!IsChild(hWnd, m->wParam))) {
  58.         PostMessage(
  59.             hWnd, m->message, m->wParam, m->lParam
  60.         );
  61.         }
  62.         break;
  63.  
  64.     default:
  65.         break;
  66.     }
  67. }
  68.  
  69. void PropagateKeyboardMouse(LPMSG m) {
  70.     HWND hWnd;
  71.  
  72.     switch (m->message) {
  73.  
  74.     case WM_MOUSEMOVE:
  75.     case WM_LBUTTONDOWN:
  76.     case WM_MBUTTONDOWN:
  77.     case WM_RBUTTONDOWN:
  78.     case WM_LBUTTONUP:
  79.     case WM_MBUTTONUP:
  80.     case WM_RBUTTONUP:
  81.     case WM_CHAR:
  82.  
  83.             hWnd = GetParent(m->hwnd);
  84.         if (hWnd != NULL) {
  85.         PostMessage(hWnd, m->message, m->wParam, m->lParam);
  86.         }
  87.         break;
  88.  
  89.     default: break;
  90.     }
  91. }
  92.  
  93. HWND GetSourceWindow () {
  94.     HWND hFocusWindow = GetFocus();
  95.  
  96.     if (IsChild(hFocusWindow, hnewWindow)) {
  97.     return hnewWindow;
  98.     }
  99.     return hFocusWindow;
  100. }
  101.  
  102. void Interactor::Listen (Sensor* s) {
  103.     cursensor = s;
  104. }
  105.  
  106. int Interactor::Fileno () {
  107.     return 0;
  108. }
  109.  
  110. boolean Interactor::GetEvent (Event& m, boolean remove) {
  111.     MSG& msg = m.rep->Message();
  112.     HWND hwindow;
  113.     Interactor* i = nil;
  114.     Cursor* cursor;
  115.     void* c;
  116.  
  117.     GetMessage(&msg,NULL,0,0);
  118.     switch (msg.message) {
  119.  
  120.     case WM_SHOWWINDOW:
  121.         if (_world->itable()->Find(i, (void*)msg.hwnd)) {
  122.         if (msg.wParam != 0) {
  123.             i->SendActivate();
  124.         } else {
  125.             i->SendDeactivate();
  126.         }
  127.         SetDummyOldWindow(msg.hwnd);
  128.         EnterLeaveMessage();
  129.         }
  130.         return false;
  131.  
  132.     case WM_PAINT:
  133.         if (_world->itable()->Find(i, (void*)msg.hwnd)) {
  134.         i->SendRedraw();
  135.         } else {
  136.                 PAINTSTRUCT ps;
  137.                 BeginPaint(msg.hwnd, &ps);
  138.                 EndPaint(msg.hwnd, &ps);
  139.             }
  140.         return false;
  141.  
  142.     case WM_MOVE:
  143.         if (_world->itable()->Find(i, (void*)msg.hwnd)) {
  144.         i->SendResize(
  145.             LOWORD(msg.lParam), HIWORD(msg.lParam),
  146.             i->canvas->width, i->canvas->height
  147.         );
  148.         SetDummyOldWindow(msg.hwnd);
  149.         EnterLeaveMessage();
  150.         }
  151.         return false;
  152.  
  153.     case WM_SIZE:
  154.         if (_world->itable()->Find(i, (void*)msg.hwnd)) {
  155.                 if (msg.wParam == SIZEICONIC) {
  156.                     const char* name = i->GetIconName();
  157.                     if (name) {
  158.                         SetWindowText(msg.hwnd, (LPSTR)name);
  159.                     }
  160.                 } else {
  161.                     const char* name = i->rep->GetWndName();
  162.                     if (name) {
  163.                         SetWindowText(msg.hwnd, (LPSTR)name);
  164.                     }
  165.                 }
  166.  
  167.         Coord x, y;
  168.         i->GetOrigin(x, y);
  169.         i->SendResize(
  170.             x, y, LOWORD(msg.lParam), HIWORD(msg.lParam)
  171.         );
  172.         SetDummyOldWindow(msg.hwnd);
  173.         EnterLeaveMessage();
  174.         }
  175.         return false;
  176.  
  177.     case WM_TIMER:
  178.         EnterLeaveMessage();
  179.         return false;
  180.  
  181.     case WM_MOUSEMOVE:
  182.         if (_world->itable()->Find(i, (void*)msg.hwnd) &&
  183.         msg.hwnd != _world->root()) {
  184.  
  185.         cursor = i->GetCursor();
  186.         c = (cursor != nil) ? cursor->Id() : defaultCursor->Id();
  187.         ::SetCursor((HCURSOR)c);
  188.         }
  189.  
  190.         EnterLeaveMessage();
  191.         hwindow = msg.hwnd;
  192.         break;
  193.  
  194.     case WM_ENTERWINDOW:
  195.     case WM_LEAVEWINDOW:
  196.         hwindow = msg.hwnd;
  197.         break;
  198.  
  199.     case WM_KEYDOWN:
  200.             msg.hwnd = GetSourceWindow();
  201.         TranslateMessage(&msg);
  202.         return false;
  203.  
  204.     case WM_CHAR:
  205.             hwindow = msg.hwnd;
  206.         break;
  207.  
  208.     case WM_LBUTTONDOWN:
  209.         if (grabButton == NOGRAB) {
  210.         grabButton = LEFTGRAB;
  211.                 SetCapture(msg.hwnd);
  212.         }
  213.         hwindow = msg.hwnd;
  214.         break;
  215.  
  216.     case WM_MBUTTONDOWN:
  217.         if (grabButton == NOGRAB) {
  218.         grabButton = MIDDLEGRAB;
  219.                 SetCapture(msg.hwnd);
  220.         }
  221.         hwindow = msg.hwnd;
  222.         break;
  223.  
  224.     case WM_RBUTTONDOWN:
  225.         if (grabButton == NOGRAB) {
  226.         grabButton = RIGHTGRAB;
  227.                 SetCapture(msg.hwnd);
  228.         }
  229.         hwindow = msg.hwnd;
  230.         break;
  231.  
  232.     case WM_LBUTTONUP:
  233.         if (grabButton == LEFTGRAB) {
  234.         grabButton = NOGRAB;
  235.         ReleaseCapture();
  236.                 msg.hwnd = GetSourceWindow();
  237.         }
  238.         hwindow = msg.hwnd;
  239.         break;
  240.  
  241.     case WM_MBUTTONUP:
  242.         if (grabButton == MIDDLEGRAB) {
  243.         grabButton = NOGRAB;
  244.         ReleaseCapture();
  245.                 msg.hwnd = GetSourceWindow();
  246.         }
  247.         hwindow = msg.hwnd;
  248.         break;
  249.  
  250.     case WM_RBUTTONUP:
  251.         if (grabButton == RIGHTGRAB) {
  252.         grabButton = NOGRAB;
  253.         ReleaseCapture();
  254.                 msg.hwnd = GetSourceWindow();
  255.         }
  256.         hwindow = msg.hwnd;
  257.         break;
  258.  
  259.     case WM_SETFOCUS:
  260.     case WM_KILLFOCUS:
  261.         hwindow = msg.hwnd;
  262.         break;
  263.  
  264.     default:
  265.         DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
  266.         return false;
  267.     }
  268.  
  269.     /* only input events should get here */
  270.  
  271.     if (!_world->itable()->Find(i, (void*)hwindow)) {
  272.     return false;
  273.     } else {
  274.     PropagateEnterLeave(&msg);
  275.     if ((i->cursensor == nil) || (!i->cursensor->Interesting(m))) {
  276.         PropagateKeyboardMouse(&msg);
  277.         return false;
  278.     }
  279.     }
  280.  
  281.     m.target = i;
  282.     m.y = i->ymax - m.y;
  283.  
  284.     if (!remove) {
  285.     PostMessage(msg.hwnd, msg.message, msg.wParam, msg.lParam);
  286.     }
  287.     return true;
  288. }
  289.  
  290. /*
  291.  * Check to see if any input events of interest are pending.
  292.  * This routine will return true even if the event is for another interactor.
  293.  */
  294.  
  295. boolean Interactor::Check () {
  296.     Event event;
  297.  
  298.     while (PeekMessage(
  299.                &event.Rep()->Message(), NULL, 0, 0, PM_NOREMOVE | PM_NOYIELD
  300.            )) {
  301.     if (GetEvent(event, false))
  302.         return true;
  303.     }
  304.     return false;
  305. }
  306.  
  307. int Interactor::CheckQueue () {
  308.     MSG msg;
  309.     if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE | PM_NOYIELD) != 0) {
  310.     return (int)true;
  311.     }
  312.     return (int)false;
  313. }
  314.  
  315. void Interactor::SendRedraw () {
  316.     PAINTSTRUCT ps;
  317.  
  318.     BeginPaint((HWND)canvas->id, &ps);
  319.  
  320.     int w = ps.rcPaint.right - ps.rcPaint.left;
  321.     int h = ps.rcPaint.bottom - ps.rcPaint.top;
  322.  
  323.     if (w > 0 && h > 0) {
  324.         Redraw(
  325.             ps.rcPaint.left,
  326.             ymax - ps.rcPaint.bottom,
  327.             ps.rcPaint.right,
  328.             ymax - ps.rcPaint.top
  329.         );
  330.     }
  331.  
  332.     EndPaint((HWND)canvas->id, &ps);
  333. }
  334.  
  335. void Interactor::SendResize (Coord x, Coord y, int w, int h) {
  336.     left = x;
  337.     bottom = parent->ymax - y - h + 1;
  338.     if (canvas->width != w || canvas->height != h) {
  339.        canvas->width = w;
  340.        canvas->height = h;
  341.        xmax = w - 1;
  342.        ymax = h - 1;
  343.        Resize();
  344.     }
  345. }
  346.  
  347. void Interactor::SendActivate () {
  348.     canvas->status = CanvasMapped;
  349.     Activate();
  350. }
  351.  
  352. void Interactor::SendDeactivate () {
  353.     canvas->status = CanvasUnmapped;
  354.     Deactivate();
  355. }
  356.  
  357. void Interactor::Poll (Event& e) {
  358.     POINT p;
  359.     int state;
  360.  
  361.     GetCursorPos(&p);
  362.     e.wx = p.x;
  363.     e.wy = p.y;
  364.     ScreenToClient((HWND)canvas->id, &p);
  365.     e.x = p.x;
  366.     e.y = ymax - p.y;
  367.     e.FindWorld (canvas->id);
  368.  
  369.     state = GetAsyncKeyState(VK_CONTROL);
  370.     e.control = (state & 0x8000) != 0;
  371.     state = GetAsyncKeyState (VK_SHIFT);
  372.     e.shift = (state & 0x8000) != 0;
  373.  
  374.     state = GetAsyncKeyState (VK_LBUTTON);
  375.     e.leftmouse = (state & 0x8000) != 0;
  376.     state = GetAsyncKeyState (VK_MBUTTON);
  377.     e.middlemouse = (state & 0x8000) != 0;
  378.     state = GetAsyncKeyState (VK_RBUTTON);
  379.     e.rightmouse = (state & 0x8000) != 0;
  380. }
  381.  
  382. void Interactor::Flush () {
  383. }
  384.  
  385. void Interactor::Sync () {
  386. }
  387.  
  388. void Interactor::GetRelative (Coord& x, Coord& y, Interactor* rel) {
  389.     register Interactor* t, * r;
  390.     Coord tx, ty, rx, ry;
  391.  
  392.     if (parent == nil) {
  393.     if (rel == nil || rel->parent == nil) {
  394.         // world relative to world -- nop
  395.         return;
  396.     }
  397.     // world relative to interactor is relative to interactor's l, b
  398.     rx = 0; ry = 0;
  399.     rel->GetRelative(rx, ry);
  400.     x = x - rx;
  401.     y = y - ry;
  402.     return;
  403.     }
  404.     tx = x; ty = y;
  405.     t = this;
  406.     for (t = this; t->parent->parent != nil; t = t->parent) {
  407.     tx += t->left;
  408.     ty += t->bottom;
  409.     }
  410.     if (rel == nil || rel->parent == nil) {
  411.     r = nil;
  412.     } else {
  413.     rx = 0; ry = 0;
  414.     for (r = rel; r->parent->parent != nil; r = r->parent) {
  415.         rx += r->left;
  416.         ry += r->bottom;
  417.     }
  418.     }
  419.     if (r == t) {
  420.     // this and rel are within same top-level interactor
  421.     x = tx - rx;
  422.     y = ty - ry;
  423.     } else {
  424.     Interactor* w;
  425.     w = (rel == nil) ? t->parent : rel;
  426.  
  427.     POINT p;
  428.     p.x = x;
  429.     p.y = ymax - y;
  430.     ClientToScreen((HWND)canvas->id, &p);
  431.     ScreenToClient((HWND)w->canvas->id, &p);
  432.     x = p.x;
  433.     y = w->ymax - p.y;
  434.     }
  435. }
  436.  
  437. void Interactor::DoSetCursor (Cursor* c) {
  438.     HCURSOR hCursor = (c != nil) ?
  439.                       (HCURSOR)c->Id() : (HCURSOR)defaultCursor->Id();
  440.     ::SetCursor((HCURSOR)hCursor);
  441.  
  442. }
  443.  
  444. void Interactor::DoSetName (const char* s) {
  445.     SetWindowText((HWND)canvas->id, (LPSTR)s);
  446. }
  447.  
  448. void Interactor::DoSetGeometry() {
  449. /*    Coord x, y;
  450.     unsigned int w, h;
  451.     x = left;
  452.     y = bottom;
  453.     World* world = GetWorld();
  454.     unsigned int m = world->GetGeometry(this, x, y, w, h);
  455.     if (m != 0 && w > 0 && h > 0) {
  456.     Coord new_top = world->ymax - y - h;
  457.     MoveWindow((HWND)canvas->id, x, new_top, w, h, false);
  458.     left = x;
  459.     bottom = y;
  460.     xmax = w - 1;
  461.     ymax = h - 1;
  462.     canvas->width = w;
  463.     canvas->height = h;
  464.     Resize();
  465.     }
  466. */
  467. }
  468.  
  469. void Interactor::DoSetGroupLeader (Interactor* leader) {
  470. }
  471.  
  472. void Interactor::DoSetTransientFor (Interactor* owner) {
  473. }
  474.  
  475. void Interactor::DoSetIconName (const char* name) {
  476. }
  477.  
  478. void Interactor::DoSetIconBitmap (Bitmap* bitmap) {
  479. }
  480.  
  481. void Interactor::DoSetIconMask (Bitmap* mask) {
  482. }
  483.  
  484. void Interactor::DoSetIconInteractor (Interactor* icon) {
  485.     Canvas* dummycanvas = nil;
  486.     Canvas*& iconcanvas = icon ? icon->canvas : dummycanvas;
  487.     if (icon != nil) {
  488.     PlaceIcon(icon, iconcanvas);
  489.     }
  490. }
  491.  
  492. void Interactor::DoSetIconGeometry (const char* g) {
  493. /*    if (g!= nil) {
  494.     Coord x = 0;
  495.     Coord y = 0;
  496.     unsigned int w = shape->width;
  497.     unsigned int h = shape->height;
  498.     Bitmap* b = GetIconBitmap();
  499.     if (b != nil) {
  500.         w = b->Width();
  501.         h = b->Height();
  502.     }
  503.     Interactor* icon = GetIconInteractor();
  504.     if (icon != nil) {
  505.         w = icon->GetShape()->width;
  506.         h = icon->GetShape()->height;
  507.     }
  508.  
  509.     World* world = GetWorld();
  510.     unsigned r = world->ParseGeometry(g, x, y, w, h);
  511.     if ((r & GeomXNegative) != 0) {
  512.         x = world->Width() + x -w;
  513.     }
  514.     if ((r & GeomYNegative) != 0) {
  515.         y = world->Height() + y - h;
  516.     }
  517.     }
  518. */
  519. }
  520.  
  521. void Interactor::Iconify () {
  522.     Interactor* icon_ia = GetIconInteractor();
  523.     if (canvas != nil && canvas->status == CanvasMapped) {
  524.     canvas->status = CanvasUnmapped;
  525.     if (icon_ia == nil) {
  526.         CloseWindow((HWND)canvas->id);
  527.     } else {
  528.         ShowWindow((HWND)canvas->id, SW_HIDE);
  529.         Canvas* c = icon_ia->GetCanvas();
  530.         if (c != nil && c->status == CanvasUnmapped) {
  531.         ShowWindow((HWND)c->id, SW_SHOWNORMAL);
  532.         c->status = CanvasMapped;
  533.         }
  534.     }
  535.     }
  536. }
  537.  
  538. void Interactor::DeIconify () {
  539.     Interactor* icon_ia = GetIconInteractor();
  540.     if (canvas != nil) {
  541.     if (canvas->status == CanvasUnmapped) {
  542.         if (icon_ia == nil) {
  543.         OpenIcon((HWND)canvas->id);
  544.         return;
  545.         } else {
  546.         Canvas* c = icon_ia->GetCanvas();
  547.         if (c != nil) {
  548.             if (c->status == CanvasMapped) {
  549.             ShowWindow((HWND)c->id, SW_HIDE);
  550.             c->status = CanvasUnmapped;
  551.             }
  552.         }
  553.         }
  554.         ShowWindow((HWND)canvas->id, SW_SHOWNORMAL);
  555.         canvas->status = CanvasMapped;
  556.     }
  557.     }
  558. }
  559.  
  560. void Interactor::GetOrigin(Coord& x, Coord& y) {
  561.     RECT rect;
  562.     GetWindowRect((HWND)canvas->id, &rect);
  563.     if (parent->parent != nil) {
  564.         POINT p;
  565.         p.x = rect.left;
  566.         p.y = rect.top;
  567.         ScreenToClient((HWND)parent->canvas->id, &p);
  568.         x = p.x;
  569.         y = p.y;
  570.     return;
  571.     }
  572.     x = rect.left + _world->XBorder;
  573.     y = rect.top + _world->YBorder + _world->YCaption;
  574.     return;
  575. }
  576.  
  577.